package com.example.armmvvm.ui.customdraw.view

import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.ViewGroup
import androidx.core.view.children

/**
 * @author 创建人 ：yanghaozhang
 * @version 1.0
 * @package 包名 ：com.example.armmvvm.ui.customdraw.view
 * @createTime 创建时间 ：2022/2/26
 * @modifyBy 修改人 ：
 * @modifyTime 修改时间 ：
 * @modifyMemo 修改备注：
 */
class TagView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    val childrenBounds = mutableListOf<Rect>()

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSpecSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSpecSize = MeasureSpec.getSize(heightMeasureSpec)

        var widthUsed = 0
        var heightUsed = 0

        var maxLineHeight = 0

        for ((index, child) in children.withIndex()) {
            // 测量子View的时候不widthUsed和heightUsed都给的0,就是为了不让子View有限制
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0)
            val bounds = childrenBounds.getOrNull(index) ?: Rect().also { childrenBounds.add(it) }
            // 如果屏幕宽度已经不满足放下该子View,则进行换行
            if (child.measuredWidth + widthUsed > widthSpecSize) {
                widthUsed = 0
                heightUsed += maxLineHeight
                maxLineHeight = 0
            }
            // 保存子View的测量结果区域,在onLayout的时候使用来排版子View
            bounds.set(widthUsed, heightUsed, widthUsed + child.measuredWidth, heightUsed + child.measuredHeight)
            // 保存该行最大高度,用于换行
            maxLineHeight = maxOf(maxLineHeight, child.measuredHeight)
            widthUsed += child.measuredWidth
        }
        // 加上最后一行的高度
        heightUsed += maxLineHeight
        setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(heightUsed, heightSpecMode))
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        for ((index, child) in children.withIndex()) {
            val rect = childrenBounds[index]
            child.layout(rect.left, rect.top, rect.right, rect.bottom)
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }
}